package olympicgameslogic;

import java.io.Serializable;
import java.util.Comparator;

/**
 * 
 * @author Nuno
 */
public class Athlete implements OurComparable, Comparable, Serializable{

   @Override
   public int compareTo(Object o) {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   /**
    * 
    */
   public static enum GENDER {

      /**
       * 
       */
      MALE,
      /**
       *
       */
      FEMALE,
      /**
       *
       */
      UNDEF
   }
   /**
    * 
    */
   public static Athlete.GENDER[] genders = {Athlete.GENDER.MALE, Athlete.GENDER.FEMALE, Athlete.GENDER.UNDEF};
   private String name;
   private GENDER sex;
   private Nation nation;
   private Modality modality;
   private int goldMedals = 0;
   private int silverMedals = 0;
   private int bronzeMedals = 0;
   private int totalMedals = 0;
   private LinkedList<Medal> medalsAthlete = new LinkedList();

   /**
    * 
    */
   public Athlete() {
   }

   /**
    * 
    * @param name
    * @param sex
    * @param nation
    * @param modality
    */
   public Athlete(String name, GENDER sex, Nation nation, Modality modality) {
      setName(name);
      setSex(sex);
      setNation(nation);
      setModality(modality);

   }

   /**
    * 
    * @param name
    * @param sex
    * @param modality
    */
   public Athlete(String name, GENDER sex, Modality modality) {
      this(name, sex, null, modality);

   }

   /**
    * 
    * @param name
    * @param sex
    * @param nation
    */
   public Athlete(String name, GENDER sex, Nation nation) {
      this(name, sex, nation, null);
   }

   /**
    * 
    * @param name
    * @param nation
    * @param modality
    */
   public Athlete(String name, Nation nation, Modality modality) {
      this(name, Athlete.GENDER.UNDEF, nation, modality);
   }

   /**
    * 
    * @param name
    * @param modality
    */
   public Athlete(String name, Modality modality) {
      this(name, GENDER.UNDEF, null, modality);
   }

   /**
    * 
    * @param name
    */
   public Athlete(String name) {
      this(name, GENDER.UNDEF, null, null);

   }

   /**
    * 
    * @param name
    * @param nation
    */
   public Athlete(String name, Nation nation) {
      this(name, GENDER.UNDEF, nation, null);

   }

   /**
    * @return the name
    */
   public String getName() {
      return name;
   }

   /**
    * @return the sex
    */
   public GENDER getSex() {
      return sex;
   }

   /**
    * @return the nation
    */
   public Nation getNation() {
      return nation;
   }

   /**
    * @return the modality
    */
   public Modality getModality() {
      return modality;
   }

   /**
    * @param name the name to set
    */
   public void setName(String name) {
      this.name = name;
   }

   /**
    * @param sex the sex to set
    */
   public void setSex(GENDER sex) {
      this.sex = sex;
   }

   /**
    * @param nation the nation to set
    */
   public void setNation(Nation nation) {
      this.nation = nation;
   }

   /**
    * @param modality the modality to set
    */
   public void setModality(Modality modality) {
      this.modality = modality;
   }

   @Override
   public String toString() {
      return getName() + "-" + getModality() + "-" + nation.getCode() + "-" + getSex();
   }

   /**
    * 
    * @param obj
    * @return
    */
   @Override
   public boolean isEqual(Object obj) {
      return ((obj instanceof Athlete && name.trim().equalsIgnoreCase(((Athlete) obj).getName().trim())) && this.nation.equals(((Athlete) obj).getNation()));
   }

   /**
    * 
    * @param m
    */
   public void addMedal(Medal m) {
      switch (m.getMedalType()) {
	 case GOLD:
	    goldMedals++;
	 case SILVER:
	    silverMedals++;
	 case BRONZE:
	    bronzeMedals++;
      }
      this.medalsAthlete.add(m);
   }

   /**
    * 
    * @return
    */
   public LinkedList<Medal> getMedals() {
      return medalsAthlete;
   }

   /**
    * 
    * @return
    */
   public String mostrarMedalhas() {
      return "" + medalsAthlete;
   }

   /**
    * 
    * @return
    */
   public int getTotalMedals() {
      return medalsAthlete.getSize();
   }

   /**
    * 
    * @param medalType
    * @return
    */
   public int getMedals(Medal.MEDALTYPE medalType) {
      int counter = 0;
      for (Medal m : medalsAthlete) {
	 if (m.getMedalType().equals(medalType)) {
	    counter++;
	 }
      }
      return counter;
   }

   /**
    * 
    * @param e
    * @return
    */
   public int getTotalEditionMedals(Edition e) {
      int counter = 0;
      for (Medal m : medalsAthlete) {
	 if (m.getEdition().equals(e)) {
	    counter++;
	 }
      }
      return counter;
   }
   
   /**
    * 
    * @param e
    * @param type
    * @return
    */
   public int getEditionMedals(Edition e, Medal.MEDALTYPE type ) {
      int counter = 0;
      for (Medal m : medalsAthlete) {
	 if (m.getEdition().equals(e) && m.getMedalType().equals(type)) {
	    counter++;
	 }
      }
      return counter;
   }

   /**
    * 
    * @return
    */
   public int getMedalsWeighted() {
      int totalWeight = 0;
      //this.bronzeMedals = this.silverMedals = this.goldMedals = 0;
      for (Medal medal : medalsAthlete) {
	 if (medal.getMedalType().equals(Medal.MEDALTYPE.GOLD)) {
	    totalWeight = totalWeight + 3;


	 } else if (medal.getMedalType().equals(Medal.MEDALTYPE.SILVER)) {
	    totalWeight = totalWeight + 2;

	 } else if ((medal.getMedalType().equals(Medal.MEDALTYPE.BRONZE))) {
	    totalWeight = totalWeight + 1;
	 }

      }
      return totalWeight;

   }

   /**
    * 
    */
   public static class MedalsAbsoluteComparator implements Comparator {

      public int compare(Object o1, Object o2) {
	 if (!(o1 instanceof Athlete) || !(o2 instanceof Athlete)) {
	    throw new ClassCastException();
	 }


	 Athlete a1 = (Athlete) o1;
	 Athlete a2 = (Athlete) o2;

	 return (int) (a2.getMedals().size() - a1.getMedals().size());
      }
   }

   /**
    * 
    */
   public static class MedalsWeightedComparator implements Comparator {

      public int compare(Object o1, Object o2) {
	 if (!(o1 instanceof Athlete) || !(o2 instanceof Athlete)) {
	    throw new ClassCastException();
	 }


	 Athlete a1 = (Athlete) o1;
	 Athlete a2 = (Athlete) o2;

	 return (int) (a2.getMedalsWeighted() - a1.getMedalsWeighted());
      }
   }

   /**
    * 
    */
   public static class NameSorter implements Comparator {

      public int compare(Object o1, Object o2) {
	 if (!(o1 instanceof Athlete) || !(o2 instanceof Athlete)) {
	    throw new ClassCastException();
	 }


	 Athlete a1 = (Athlete) o1;
	 Athlete a2 = (Athlete) o2;

	 return (int) (a1.getName().compareToIgnoreCase(a2.getName()));
      }
   }
}